package com.ruoyi.driver.service.impl;

import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.driver.domain.Car;
import com.ruoyi.driver.enums.IdCardSideEnum;
import com.ruoyi.driver.mapper.CarMapper;
import com.ruoyi.driver.service.IDriverService;
import com.ruoyi.driver.utils.ShuMaiUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.time.Period;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 司机Service业务层处理
 * 
 * @author lipengze
 * @date 2024-10-17
 */
@Slf4j
@Service
public class DriverServiceImpl implements IDriverService
{
    @Autowired
    private CarMapper carMapper;
    @Resource
    private ShuMaiUtils shuMaiUtils;
    @Value("${shumai.idUrl}")
    private String idUrl;
    @Value("${shumai.driving_licenceUrl}")
    private String drivingLicenceUrl;
    @Value("${shumai.vehicle_licenceUrl}")
    private String vehicleLicenceUrl;

    /**
     * 身份证校验逻辑
     * @param file
     * @return
     */
    @Override
    public AjaxResult idCardOcr(MultipartFile file) throws IOException {

        // 上传文件到 OSS
        String ossPath = shuMaiUtils.uploadFile(file);
        Map<String, Object> map = new HashMap<>();
        map.put("idCardImg",ossPath);
        Map<String, Object> apiResponse = handleApiResponse(idUrl, file);
        //初始化一个统一的返回结果
        AjaxResult ajaxResult = null;
        //获取第一层data对象
        Map<String,Object> data = (Map<String, Object>) apiResponse.get("data");
        //判断正反面  side	身份证⽅方向信息。front 代表身份证正面(⼈像面)， back 代表身份证反面(国徽⾯)
        if (IdCardSideEnum.BACK.getDetail().equals(data.get("side"))) {
            ajaxResult = idCardOcrBack(apiResponse,map);
        } else {
            ajaxResult = idCardOcrFront(apiResponse,map);
        }
        return ajaxResult;
    }

    /**
     * 正面校验
     * @param jsonResult
     * @return
     */
    public AjaxResult idCardOcrFront(Map<String,Object> jsonResult,Map<String, Object> map) {
        //获取第一层  data对象
        Map<String,Object> data = (Map<String, Object>) jsonResult.get("data");
        //获取 第二层 info对象
        Map<String,Object> info = (Map<String, Object>)data.get("info");
        //获取年龄
        Integer year = Integer.parseInt(info.get("year").toString());
        Integer month = Integer.parseInt(info.get("month").toString());
        Integer day = Integer.parseInt(info.get("day").toString());
        // 计算年龄
        LocalDate birthDate = LocalDate.of(year, month, day);
        LocalDate currentDate = LocalDate.now();
        int age = Period.between(birthDate, currentDate).getYears();
        // 判断年龄是否大于21岁小于60岁
        if (age <= 21 || age >= 60) {
            throw new RuntimeException("年龄不符合要求");
        }
        info.put("idCardImg",map.get("idCardImg"));
        return AjaxResult.success("扫描正面成功",info);
    }
    /**
     * 反面校验
     * @param jsonResult
     * @return
     */
    public AjaxResult idCardOcrBack(Map<String,Object> jsonResult,Map<String, Object> map) {
        //获取第一层  data对象
        Map<String,Object> data = (Map<String, Object>) jsonResult.get("data");
        //获取 第二层 info对象
        Map<String,Object> info = (Map<String, Object>)data.get("info");
        //此处判断身份证是否过期
        if (Boolean.FALSE.equals(info.get("timelimit"))) {
            throw new RuntimeException("身份证过期");
        }
        info.put("idCardImg",map.get("idCardImg"));
        return AjaxResult.success("扫描反面成功",info);
    }
    /**
     * 驾驶证校验
     * @param file
     * @return
     */
    @Override
    public AjaxResult drivingOcr(MultipartFile file,Map<String,Object> map) throws IOException {
        // 上传文件到 OSS
        String ossPath = shuMaiUtils.uploadFile(file);

        Map<String, Object> apiResponse = handleApiResponse(drivingLicenceUrl, file);

        /*有效期校验  valid_date */
        //获取第一层  data对象
        Map<String,Object> data = (Map<String, Object>) apiResponse.get("data");
        //获取 第二层 result对象
        Map<String,Object> result = (Map<String, Object>)data.get("result");
        //获取第三层 page_a对象
        Map<String, Object> pageA = (Map<String, Object>) result.get("page_a");

        //获取驾驶证上的身份证信息
        String id = (String) pageA.get("id");
        String driverName = (String) pageA.get("name");
        //获取前端传回来的身份证信息
        String number = (String) map.get("number");
        String idCardName = (String) map.get("name");

        if (!id.equals(number) || !driverName.equals(idCardName)) {
            return AjaxResult.error("身份信息不一致", null);
        }

        String[] split = pageA.get("valid_date").toString().split("至");
        //调用数脉工具类的驾驶证有效期校验方法  如果发生异常 则抛出异常 并被全局异常拦截
        shuMaiUtils.validateDateRange(split[0], split[1]);

        result.put("drivingLicenseUrl", ossPath);

        return AjaxResult.success("驾驶证有效", result);
    }

    /**
     * 行驶证
     * @param file 文件
     * @return
     * @throws IOException
     */
    @Override
    public AjaxResult vehicleOcr(MultipartFile file) throws IOException {
        // 上传文件到 OSS
        String ossPath = shuMaiUtils.uploadFile(file);

        Map<String, Object> apiResponse = handleApiResponse(vehicleLicenceUrl, file);
        //获取第一层  data对象
        Map<String,Object> data = (Map<String, Object>) apiResponse.get("data");
        //获取 第二层 result对象
        Map<String,Object> result = (Map<String, Object>)data.get("result");
        result.put("vehicleLicenseUrl",ossPath);
        return AjaxResult.success("扫描成功",result);
    }

    /**
     * 活体检测 && 特征检测
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public AjaxResult recognizeFace(MultipartFile file,Map<String,Object> map) throws IOException {
        //繁琐的多次请求封装到工具类中
        Map<String, Object> resultMap = shuMaiUtils.recognizeFace(file, map);
        Map<String, Object> data = (Map<String, Object>) resultMap.get("data");
        Integer incorrect = (Integer) data.get("incorrect");
        if (incorrect == 100) {
            AjaxResult.success(resultMap.get("msg").toString(), data);
        }
        return AjaxResult.error(resultMap.get("msg").toString(), data);
    }
    /**
     * 私有的  发送请求  和  请求结果处理
     * @param requestUrl  请求地址
     * @param file  文件
     * @return
     * @throws IOException
     */
    private Map<String, Object> handleApiResponse(String requestUrl,MultipartFile file) throws IOException {
        //发送 POST 请求 并获取结果
        Map<String, Object> apiResponse = shuMaiUtils.processApiRequest(requestUrl, file);
        //调用统一异常结果方法  他会自动调用扫描方法  如果失败会异常
        shuMaiUtils.handleFailure(apiResponse);
        return apiResponse;
    }

    /**
     * 查询司机
     * 
     * @param id 司机主键
     * @return 司机
     */
    @Override
    public Car selectCarById(Long id)
    {
        return carMapper.selectCarById(id);
    }

    /**
     * 查询司机列表
     * 
     * @param car 司机
     * @return 司机
     */
    @Override
    public List<Car> selectCarList(Car car)
    {
        return carMapper.selectCarList(car);
    }

    /**
     * 新增司机
     * 
     * @param car 司机
     * @return 结果
     */
    @Override
    public int insertCar(Car car)
    {
        return carMapper.insertCar(car);
    }

    /**
     * 修改司机
     * 
     * @param car 司机
     * @return 结果
     */
    @Override
    public int updateCar(Car car)
    {
        return carMapper.updateCar(car);
    }

    /**
     * 批量删除司机
     * 
     * @param ids 需要删除的司机主键
     * @return 结果
     */
    @Override
    public int deleteCarByIds(Long[] ids)
    {
        return carMapper.deleteCarByIds(ids);
    }

    /**
     * 删除司机信息
     * 
     * @param id 司机主键
     * @return 结果
     */
    @Override
    public int deleteCarById(Long id)
    {
        return carMapper.deleteCarById(id);
    }


}
